package com.yxhl.zoume.core.busticket.ui.fragment;

import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.OvershootInterpolator;
import android.widget.EditText;
import android.widget.TextView;

import com.afollestad.materialdialogs.MaterialDialog;
import com.yxhl.protobuf.EndStationEntry;
import com.yxhl.zoume.R;
import com.yxhl.zoume.common.ui.custom.QuickIndexBar;
import com.yxhl.zoume.common.ui.fragment.BaseFragment;
import com.yxhl.zoume.core.busticket.model.BusSelectCityEntity;
import com.yxhl.zoume.core.busticket.model.ObservableLetterEntity;
import com.yxhl.zoume.core.busticket.model.ZMSelectStartCityEntity;
import com.yxhl.zoume.core.busticket.presenter.ArrivalCitiesPresenter;
import com.yxhl.zoume.core.busticket.presenter.BusSearchStationPresenter;
import com.yxhl.zoume.core.busticket.ui.activity.BusStationsListActivity;
import com.yxhl.zoume.core.busticket.ui.adapter.BusArrivalStationAdapter;
import com.yxhl.zoume.core.busticket.ui.adapter.StationType;
import com.yxhl.zoume.core.busticket.ui.info.ZMScheduleType;
import com.yxhl.zoume.core.busticket.view.BusArrivalStationView;
import com.yxhl.zoume.core.busticket.view.SearchStationView;
import com.yxhl.zoume.di.component.busticket.BusStationComponent;
import com.yxhl.zoume.utils.CollectionUtils;
import com.yxhl.zoume.utils.LOG;
import com.yxhl.zoume.utils.alphabet.AlphabetHelper;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.OnTextChanged;
import jp.wasabeef.recyclerview.animators.SlideInUpAnimator;
import rx.Subscriber;

/**
 * Created by vhawk on 16/3/20.
 * modify by sugarya on 16/07/25
 */
public class BusArrivalStationFragment extends BaseFragment implements BusArrivalStationView, SearchStationView {

    public static final String TAG = "BusArrivalStationFragment";
    public static final int MSG_WHAT_NOTIFY_RECYCLER_PRE = 1;
    public static final int MSG_WHAT_NOTIFY_RECYCLER_JUNIOR_ANDROID_VERSION = 2;
    public static final int MSG_WHAT_NOTIFY_RECYCLER_SENIOR_ANDROID_VERSION = 3;
    public static final int MSG_WHAT_NOTIFY_RECYCLER_ENDING = 4;
    private static final String EXTRA_START_STATION = "extra_start_station";
    private static final int RECYCLER_VIEW_ADD_DURATION = 180;

    //widgets
    @BindView(R.id.et_special_car_station_search)
    EditText mSearchInputEt;

    @BindView(R.id.recycler_bus_ticket_cities)
    RecyclerView mArrivalStationsRecyclerView;

    @BindView(R.id.tv_center_index)
    TextView mCenterIndex;

    @BindView(R.id.qib)
    QuickIndexBar mIndexBar;


    //arguments
    @Inject
    ArrivalCitiesPresenter presenter;//巴士车站查询的presenter

    @Inject
    BusSearchStationPresenter mArrivalStationSearchPresenter;//车站搜索用的presenter

    private BusArrivalStationAdapter mBusArrivalStationAdapter;//到达站数据展示适配器

    private List<BusSelectCityEntity> mBusSelectCityEntityList = new ArrayList<>();

    private BusStationComponent component;//到达站dagger component

    private MaterialDialog dialogForWaitingCities;
    private ZMSelectStartCityEntity mSelectStartCityEntity;

    private BusArrivalStationAdapter.ArrivalOnScrollListen mArrivalOnScrollListen;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_WHAT_NOTIFY_RECYCLER_PRE:
                    break;

                case MSG_WHAT_NOTIFY_RECYCLER_JUNIOR_ANDROID_VERSION:
                    waitingForQueryCities(false);
                    mBusArrivalStationAdapter.notifyDataAll();
                    //   mBusArrivalStationAdapter.notifyDataOriginally(true);
                    break;

                case MSG_WHAT_NOTIFY_RECYCLER_SENIOR_ANDROID_VERSION:
                    waitingForQueryCities(false);
                    mBusArrivalStationAdapter.notifyDataAll();
                    break;

                case MSG_WHAT_NOTIFY_RECYCLER_ENDING:
                    break;
            }
        }
    };


    public static BusArrivalStationFragment newInstance(Serializable selectStartCityEntity) {
        BusArrivalStationFragment fragment = new BusArrivalStationFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(EXTRA_START_STATION, selectStartCityEntity);
        fragment.setArguments(bundle);
        return fragment;
    }

    private void parseArguments() {
        Bundle arguments = getArguments();
        if (arguments != null && arguments.containsKey(EXTRA_START_STATION)) {
            mSelectStartCityEntity = (ZMSelectStartCityEntity) arguments.getSerializable(EXTRA_START_STATION);
        }
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        parseArguments();
        //  onRxBusEvent();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        presenter.attachView(this);
        mArrivalStationSearchPresenter.attachView(this);
        initRecyclerView();
        loadBusStations();

        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mIndexBar.setOnIndexChangeListener(new MyOnIndexChangeListener());
    }

    private void initRecyclerView() {
        mBusArrivalStationAdapter = new BusArrivalStationAdapter(
                component.context(),
                mBusSelectCityEntityList,
                StationType.STATION_TYPE_ARRIVAL);

        mArrivalStationsRecyclerView.setLayoutManager(new LinearLayoutManager(component.context()));
        mArrivalStationsRecyclerView.setItemAnimator(new SlideInUpAnimator(new OvershootInterpolator(1f)));
        mArrivalStationsRecyclerView.getItemAnimator().setAddDuration(RECYCLER_VIEW_ADD_DURATION);
        mArrivalStationsRecyclerView.setAdapter(mBusArrivalStationAdapter);


//        mArrivalOnScrollListen = mBusArrivalStationAdapter.new ArrivalOnScrollListen();
//        mArrivalStationsRecyclerView.addOnScrollListener(mArrivalOnScrollListen);
    }

    @OnTextChanged(R.id.et_special_car_station_search)
    public void searchInputTextChange(CharSequence text) {
        int length = text.length();
        if (length <= 0) {
            mBusArrivalStationAdapter.notifyDataOriginally(true);
        } else {
            mBusArrivalStationAdapter.setEnableLoadMoreData(false);
            mArrivalStationSearchPresenter.search(text.toString().trim());
        }
    }

    /**
     * 加载巴士车站数据
     */
    private void loadBusStations() {
        presenter.fetchBusStations(mSelectStartCityEntity);
    }


    @Override
    public void onPause() {
        super.onPause();
        presenter.onPause();
        mArrivalStationSearchPresenter.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        presenter.onResume();
        mArrivalStationSearchPresenter.onResume();
    }

    @Override
    public void onDestroyView() {
        if (mBusSelectCityEntityList != null) {
            int originalSize = mBusSelectCityEntityList.size();
            if (originalSize > 0) {
                mBusSelectCityEntityList.clear();
                if (mBusArrivalStationAdapter != null) {
                    mBusArrivalStationAdapter.notifyItemRangeRemoved(0, originalSize);
                }
            }
            mBusSelectCityEntityList = null;
        }
        if (mArrivalOnScrollListen != null && mArrivalStationsRecyclerView != null) {
            mArrivalStationsRecyclerView.removeOnScrollListener(mArrivalOnScrollListen);
        }

        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        presenter.onDestroy();
        mArrivalStationSearchPresenter.onDestroy();
    }

    @Override
    public void renderBusStationListResult(List<EndStationEntry> endStationList) {
        if (!CollectionUtils.isEmpty(endStationList)) {
            LOG.e(TAG, "renderBusStationListResult endStationList size = " + endStationList.size());
            final Map<String, List<BusSelectCityEntity>> alphabetMap = new HashMap<>();

            AlphabetHelper.getArrivalAlphabetObservable(endStationList)
                    .subscribe(new Subscriber<ObservableLetterEntity>() {
                        @Override
                        public void onCompleted() {
                            List<BusSelectCityEntity> beanList = AlphabetHelper.getBusAlphabetData(alphabetMap);
                            if (beanList != null && beanList.size() > 0) {
                                mArrivalStationSearchPresenter.setAlphabetMap(alphabetMap);
                                mArrivalStationSearchPresenter.setStations(beanList);

                                mBusArrivalStationAdapter.setTotalBusSelectCityEntityList(beanList);
                                if (Build.VERSION.SDK_INT >= 23) {
                                    mHandler.obtainMessage(MSG_WHAT_NOTIFY_RECYCLER_SENIOR_ANDROID_VERSION).sendToTarget();
                                } else {
                                    mHandler.obtainMessage(MSG_WHAT_NOTIFY_RECYCLER_JUNIOR_ANDROID_VERSION).sendToTarget();
                                }
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                            waitingForQueryCities(false);
                        }

                        @Override
                        public void onNext(ObservableLetterEntity observableLetterEntity) {
                            String letter = observableLetterEntity.getLetter();
                            String cityName = observableLetterEntity.getCityName();
                            String cityCode = observableLetterEntity.getCityCode();
                            List<ZMScheduleType> scheduleTypeList = observableLetterEntity.getScheduleTypeList();

                            List<BusSelectCityEntity> beanList = alphabetMap.get(letter);
                            if (beanList != null) {
                                beanList.add(new BusSelectCityEntity(cityName, cityCode, scheduleTypeList));
                            } else {
                                beanList = new LinkedList<>();
                                beanList.add(new BusSelectCityEntity(letter, ""));
                                beanList.add(new BusSelectCityEntity(cityName, cityCode, scheduleTypeList));
                                alphabetMap.put(letter, beanList);
                            }
                        }
                    });
        }
    }

    @Override
    public void waitingForQueryCities(boolean isWaiting) {
        LOG.e(TAG, "waitingForQueryCities isWaiting=" + isWaiting);
        if (isWaiting) {
            dialogForWaitingCities = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_loading)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != dialogForWaitingCities && dialogForWaitingCities.isShowing()) {
                dialogForWaitingCities.dismiss();
            }
        }
    }

    /**
     * 搜索框搜索内容回调
     *
     * @param busSelectCityEntityList
     */
    @Override
    public void onSearchResult(List<BusSelectCityEntity> busSelectCityEntityList) {
        if (busSelectCityEntityList != null && busSelectCityEntityList.size() > 0) {
            mBusSelectCityEntityList.clear();
            mBusSelectCityEntityList.addAll(busSelectCityEntityList);
        } else {
            mBusSelectCityEntityList.clear();
        }
        mBusArrivalStationAdapter.notifyDataSetChanged();
    }


    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_bus_ticket_city_list;
    }

    @Override
    protected void setupToolBar() {
        if (getActivity() instanceof BusStationsListActivity) {
            ((BusStationsListActivity) getActivity()).setToolbarTitle(getString(R.string.arrival_city_hint));
        }
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(BusStationComponent.class);
        component.inject(this);
    }

    private class MyOnIndexChangeListener implements QuickIndexBar.OnIndexChangeListener {
        @Override
        public void onIndexChange(String selectAlphabet) {
            mCenterIndex.setText(selectAlphabet);
            mCenterIndex.setVisibility(View.VISIBLE);
            int indexOf = mBusSelectCityEntityList.indexOf(new BusSelectCityEntity(selectAlphabet, ""));
            if (indexOf >= 0) {
                if (mArrivalStationsRecyclerView != null) {
                    mArrivalStationsRecyclerView.scrollToPosition(indexOf);
                }
            }
        }

        @Override
        public void onActionUp() {
            mCenterIndex.setVisibility(View.GONE);
        }
    }
}
